#include "stdafx.h"
#include "render/rendermgr.h"
#include "./basethread.h"

BaseThread::BaseThread()
: m_bTerminate(false)
, m_bModifyFlag(false)
, m_bStarted(false)
, m_bStopEvent(false)
, m_bThreadEnd(false)
{
	RenderMgr::GetInstance().OnExtRender += EventObject<OnExtRenderFunc>(this, &BaseThread::DoThreadEnd);
}

BaseThread::~BaseThread()
{
}

void BaseThread::Start()
{
	m_bStarted = true;
	m_bTerminate = false;
	m_bModifyFlag = true;

	::InitializeCriticalSection(&m_csThreadSafe);

	HANDLE hThread = (HANDLE)_beginthread(BaseThread::ThreadEntryPoint, 0, this);
}

void BaseThread::Stop()
{
	if (!m_bStarted)
	{
		return;
	}

	::EnterCriticalSection(&m_csThreadSafe);

	m_bTerminate = true;
	m_bModifyFlag = true;

	::LeaveCriticalSection(&m_csThreadSafe);
}

bool BaseThread::GetStarted()
{
	return m_bStarted;
}

bool BaseThread::CheckStates()
{
	bool bRet = false;

	::EnterCriticalSection(&m_csThreadSafe);

	if (m_bModifyFlag)
	{
		if (m_bTerminate)
		{
			bRet = true;
		}

		m_bModifyFlag = false;
	}

	::LeaveCriticalSection(&m_csThreadSafe);

	return bRet;
}

void BaseThread::ThreadFunc()
{
}

void BaseThread::ThreadEntryPoint(void* pArgList)
{
	BaseThread* pThread = reinterpret_cast<BaseThread*>(pArgList);
	pThread->ThreadFunc();

	pThread->m_bThreadEnd = true;
	pThread->m_bStarted = false;
	_endthread();
}

void BaseThread::DoThreadEnd()
{
	if (!m_bThreadEnd || m_bStopEvent)
		return;

	m_bThreadEnd = false;
	FireEvent(OnThreadEndFunc, OnThreadEnd, (this));
	RenderMgr::GetInstance().OnExtRender -= EventObject<OnExtRenderFunc>(this, &BaseThread::DoThreadEnd);
}